package com.soa.database.service;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.gson.Gson;
import com.soa.database.entity.GatewayServiceParams;
import com.soa.database.entity.GatewayServiceTest;
import com.soa.database.entity.GatewayServiceTestGroup;
import com.soa.database.entity.GatewayServiceTestGroupLog;
import com.soa.database.entity.GatewayServiceTestLog;
import com.soa.database.entity.GatewayZuulSbaNode;
import com.soa.database.thread.CompareTaskCallable;

/**
 * Created by zx on 2018/6/1.
 */
@Service
@Transactional
public class GatewayTestService {
	@PersistenceContext
	private EntityManager entityManager;

	private Session session;

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public Session getSession() {
		return this.getEntityManager().unwrap(org.hibernate.Session.class);
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public void checkService(String groupName) throws Exception {
		Gson gson = new Gson();
		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String testnum = sf.format(new Date());
		Criteria listSettingGroup = this.getSession().createCriteria(GatewayServiceTestGroup.class);
		List<GatewayServiceTestGroup> list = listSettingGroup.list();
		if(list==null || list.size()==0)return;
		GatewayServiceTestGroup gatewayServiceTestGroup = list.get(0);
		GatewayServiceTestGroupLog gatewayServiceTestGroupLog = new GatewayServiceTestGroupLog();
		gatewayServiceTestGroupLog.setTestGroupNum(testnum);
		gatewayServiceTestGroupLog.setOperateTime(new Timestamp(new Date()
				.getTime()));
		gatewayServiceTestGroupLog.setGroupId(gatewayServiceTestGroup
				.getId());
		gatewayServiceTestGroupLog.setGroupName(gatewayServiceTestGroup
				.getGroupName());
		Long allcount = 0l, successcount = 0l, errocount = 0l;
		Long startTime = System.currentTimeMillis();
		this.getSession().save(gatewayServiceTestGroupLog);
		Criteria gatewayServiceTestCriteria = this.getSession().createCriteria(GatewayServiceTest.class);
		gatewayServiceTestCriteria.add(Restrictions.eq("testGroupId", gatewayServiceTestGroup.getId()));
		List<GatewayServiceTest> gatewayServiceTestlist = gatewayServiceTestCriteria.list();
		ExecutorService pool = Executors.newCachedThreadPool();
		List<Future<String>> returnlist = new ArrayList<Future<String>>();
		for (GatewayServiceTest gatewayServiceTest : gatewayServiceTestlist) {
			GatewayServiceTestLog gatewayServiceTestLog = new GatewayServiceTestLog();
			gatewayServiceTestLog.setGatewayServiceTestGroupLog(gatewayServiceTestGroupLog);
			gatewayServiceTestLog.setOperateTime(new Timestamp(new Date().getTime()) );
			gatewayServiceTestLog.setServiceId(gatewayServiceTest.getServiceId());
			gatewayServiceTestLog.setServiceName(gatewayServiceTest.getServiceName());
			gatewayServiceTestLog.setTestId(gatewayServiceTest.getId());
			gatewayServiceTestLog.setUrl(gatewayServiceTest.getPath());
			this.getSession().save(gatewayServiceTestLog);
			Map<String, String> paramMap = new HashMap<String, String>();
			Map<String, String> headerMap = new HashMap<String, String>();
			Criteria gatewayServiceParamsCriteria = this.getSession().createCriteria(GatewayServiceParams.class);
			gatewayServiceParamsCriteria.add(Restrictions.eq("gatewayService.id", gatewayServiceTest.getServiceId()));
			gatewayServiceParamsCriteria.add(Restrictions.in("requestOrResponse", new Object[]{"request","header"}));
			List<GatewayServiceParams> requestParamslist = gatewayServiceParamsCriteria.list();
			for (GatewayServiceParams gatewayServiceParams : requestParamslist) {
				if(gatewayServiceParams.getRequestOrResponse().equals("request")){
					paramMap.put(gatewayServiceParams.getParamName(),
							gatewayServiceParams.getDemo());
				}else{
					headerMap.put(gatewayServiceParams.getParamName(),
							gatewayServiceParams.getDemo());
				}
			}
			returnlist.add(pool.submit(new CompareTaskCallable(
					gatewayServiceTest, gatewayServiceTestLog,paramMap,headerMap)));
		}
		for (Future<String> future : returnlist) {
			Map<String, Object> resultVo = gson.fromJson(future.get(),
					Map.class);
			allcount =((Double) resultVo.get("allcount")).longValue();
			successcount =((Double) resultVo.get("successcount")).longValue();
			errocount =((Double) resultVo.get("errocount")).longValue();			
			GatewayServiceTestLog gatewayServiceTestLog = this.getSession().get(GatewayServiceTestLog.class, resultVo.get("logid").toString());
			gatewayServiceTestLog.setContinueTime(((Double) resultVo.get("logContinueTime")).intValue());
			gatewayServiceTestLog.setOperateEndTime(new Timestamp(((Double) resultVo.get("logOperateEndTime")).longValue()) );
			gatewayServiceTestLog.setResponseContent(resultVo.get("logResponseContent").toString());
			gatewayServiceTestLog.setState(resultVo.get("logstate").toString());
			this.getSession().update(gatewayServiceTestLog);
			GatewayServiceTest gatewayServiceTest = this.getSession().get(GatewayServiceTest.class, resultVo.get("testid").toString());
			gatewayServiceTest.setState(resultVo.get("testState").toString());
			gatewayServiceTest.setReason(resultVo.get("testReason").toString());
			this.getSession().update(gatewayServiceTest);
		}
		long endTime = System.currentTimeMillis();
		gatewayServiceTestGroupLog.setTestCount(allcount.intValue());
		gatewayServiceTestGroupLog.setSuccessCount(successcount.intValue());
		gatewayServiceTestGroupLog.setErrorCount(errocount.intValue());
		gatewayServiceTestGroupLog
				.setContinueTime(((Long) (endTime - startTime)).intValue());
		gatewayServiceTestGroupLog.setOperateEndTime(new Timestamp(
				new Date().getTime()));
		this.getSession().update(gatewayServiceTestGroupLog);
		gatewayServiceTestGroup.setAllCount(allcount.intValue());
		gatewayServiceTestGroup.setErrorCount(errocount.intValue());
		gatewayServiceTestGroup.setSuccessCount(successcount.intValue());
		this.getSession().update(gatewayServiceTestGroup);
	}
}
